package com.yixin.hospital.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.Constant;
import com.yixin.hospital.entity.bo.GodownDrugDetail;
import com.yixin.hospital.entity.bo.PageInfo;
import com.yixin.hospital.entity.bo.PurchaseOrderDetail;
import com.yixin.hospital.entity.bo.UserDeptWorkAddressJobOffice;
import com.yixin.hospital.entity.domain.*;
import com.yixin.hospital.entity.dto.req.auditmanager.AddAuditFlowReqDTO;
import com.yixin.hospital.entity.dto.req.purchaseorder.GoDownDrugEditReqDTO;
import com.yixin.hospital.entity.dto.req.purchaseorder.GoDownDrugReqDTO;
import com.yixin.hospital.entity.dto.req.purchaseorder.PurchaseOrderAddReqDTO;
import com.yixin.hospital.entity.vo.*;
import com.yixin.hospital.enums.*;
import com.yixin.hospital.mapper.extend.PurchaseOrderExtendMapper;
import com.yixin.hospital.service.*;
import com.yixin.hospital.service.extend.AuditFlowPresetExtendService;
import com.yixin.hospital.utils.CaffeineUtils;
import com.yixin.hospital.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.yixin.hospital.common.Constant.USER_CACHE;
import static com.yixin.hospital.common.Constant.format;
import static com.yixin.hospital.enums.ResponseCodeEnum.DEPOSITORY_NOT_FOUND;

@RestController
@RequestMapping("/purchase-order")
@Api(value = "采购单管理", tags = "采购单管理")
public class PurchaseOrderController {

    @Resource
    PurchaseOrderService purchaseOrderService;
    @Resource
    DeptService deptService;
    @Resource
    PurchaseOrderDrugService purchaseOrderDrugService;
    @Resource
    PurchaseOrderOperationService purchaseOrderOperationService;
    @Resource
    AuditFlowPresetService auditFlowPresetService;
    @Resource
    AuditFlowPresetExtendService auditFlowPresetExtendService;
    @Resource
    GodownDrugService godownDrugService;
    @Resource
    DrugService drugService;
    @Resource
    DrugDepositoryDrugService drugDepositoryDrugService;
    @Resource
    DrugDepositoryService drugDepositoryService;
    @Resource
    AuditFlowDetailService auditFlowDetailService;
    @Resource
    UserService userService;
    @Resource
    AuditFlowService auditFlowService;
    @Resource
    PurchaseOrderExtendMapper purchaseOrderExtendMapper;
    @Resource
    JobDutyService jobDutyService;
    @Resource
    DrugDepositoryController drugDepositoryController;
    @Resource
    DrugFactoryService drugFactoryService;
    @Resource
    DrugDepositoryAuthController drugDepositoryAuthController;

    @GetMapping("/list")
    @ApiOperation(value = "采购单列表")
    public ApiResult<?> list(@RequestParam int currentPage, @RequestParam int pageSize,
                             @RequestParam(value = "status", required = false) Integer status,
                             @RequestParam(value = "deptId", required = false) Integer deptId,
                             @RequestParam(value = "type", required = false) String type,
                             HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        User user = userService.getById(userId);
        List<DrugDepository> drugDepositoryList = drugDepositoryService.list(new LambdaQueryWrapper<DrugDepository>().eq(DrugDepository::getDept, deptId));
        List<Long> drugDepositoryIdsByDept = drugDepositoryList.stream().map(DrugDepository::getId).collect(Collectors.toList());
        if (drugDepositoryIdsByDept.isEmpty()) {
            return ApiResult.success(new PageInfo<>(new ArrayList<>(), 0l, currentPage, pageSize));
        }
//        List<Long> drugDepositoryIdsByAuth = new ArrayList<>();
//        for (Long drugDepositoryId : drugDepositoryIdsByDept) {
//            if (drugDepositoryAuthController.checkDrugDepositoryAuth(userId, drugDepositoryId, DrugDepositoryOtpTypeEnum.PURCHASE.getCode())) {
//                drugDepositoryIdsByAuth.add(drugDepositoryId);
//            }
//        }
        IPage<PurchaseOrder> page = purchaseOrderExtendMapper.pageVo(Page.of(currentPage, pageSize), status, drugDepositoryIdsByDept, type);
        PageInfo<PurchaseOrderVO> pageInfo = new PageInfo<>();
        BeanUtil.copyProperties(page, pageInfo);
        pageInfo.setRecords(BeanUtil.copyToList(page.getRecords(), PurchaseOrderVO.class));
        for (PurchaseOrderVO record : pageInfo.getRecords()) {
            // 审批状态
            AuditFlow auditFlow = auditFlowService.getOne(new LambdaQueryWrapper<AuditFlow>().eq(AuditFlow::getFlowNo, record.getCode()));
            if (auditFlow != null) {
                record.setAuditStatus(auditFlow.getStatus());
            }
            // 查询药品库房表
            DrugDepository drugDepository = drugDepositoryService.getById(record.getApplyDepository());
            record.setApplyDepository(drugDepository.getId());
            record.setApplyDepositoryName(drugDepository.getName());
            record.setDeptName(deptService.getById(drugDepository.getDept()).getName());
            // 查询采购单药品表
            LambdaQueryWrapper<PurchaseOrderDrug> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PurchaseOrderDrug::getPurchaseOrderId, record.getId());
            queryWrapper.groupBy(PurchaseOrderDrug::getDrugCode);
            List<PurchaseOrderDrug> list = purchaseOrderDrugService.list(queryWrapper);
            record.setDrugTypeNum(list.size());
            // 定义采购总数
            int purchasesDrugNum = 0;
            // 定义总的入库数
            int allGodownNum = 0;
            for (PurchaseOrderDrug purchaseOrderDrug : list) {
                LambdaQueryWrapper<GodownDrug> godownDrugLambdaQueryWrapper = new LambdaQueryWrapper<>();
                godownDrugLambdaQueryWrapper.eq(GodownDrug::getPurchaseOrderId, record.getId());
                godownDrugLambdaQueryWrapper.eq(GodownDrug::getDrugCode, purchaseOrderDrug.getDrugCode());
                List<GodownDrug> godownDrugList = godownDrugService.list(godownDrugLambdaQueryWrapper);
                for (GodownDrug godownDrug : godownDrugList) {
                    allGodownNum += godownDrug.getPutNum();
                }
            }
            // 设置采购总数
            LambdaQueryWrapper<PurchaseOrderOperation> purchaseOrderOperationLambdaQueryWrapper = new LambdaQueryWrapper<>();
            purchaseOrderOperationLambdaQueryWrapper.eq(PurchaseOrderOperation::getPurchaseOrderId, record.getId());
            List<PurchaseOrderOperation> operationList = purchaseOrderOperationService.list(purchaseOrderOperationLambdaQueryWrapper);
            int sum = operationList.stream().mapToInt(PurchaseOrderOperation::getNum).sum();
            record.setDrugNum(sum);

            // 设置入库状态
            record.setGodownStatus(allGodownNum == 0 ? GoDownStatusEnum.PENDING.getCode() :
                    sum != allGodownNum ? GoDownStatusEnum.DOING.getCode() : GoDownStatusEnum.DONE.getCode());

            // 查询用户是否能审批
            if (record.getStatus().equals(PurchaseStatusEnum.COMMIT.getCode())) {
                LambdaUpdateWrapper<AuditFlowDetail> wrapper = new LambdaUpdateWrapper<>();
                wrapper.eq(AuditFlowDetail::getFlowNo, record.getCode());
                wrapper.eq(AuditFlowDetail::getStatus, AuditDetailStatusEnum.AUDIT_ME.getCode());
                AuditFlowDetail auditFlowDetail = auditFlowDetailService.getOne(wrapper);
                if (Objects.nonNull(auditFlowDetail)) {
                    if (user.getId().equals(auditFlowDetail.getAuditUserId())) {
                        record.setCanAudit(true);
                    }
                }
            }
        }

        return ApiResult.success(pageInfo);
    }

    @GetMapping("/detail/{id}")
    @ApiOperation(value = "采购单详情")
    public ApiResult<?> detail(@PathVariable int id) {
        // 查询采购单详情
        PurchaseOrder purchaseOrder = purchaseOrderService.getById(id);
        PurchaseOrderDetailVO purchaseOrderDetailVO = new PurchaseOrderDetailVO();
        BeanUtils.copyProperties(purchaseOrder, purchaseOrderDetailVO);
        // 查询库房
        DrugDepository drugDepository = drugDepositoryService.getById(purchaseOrderDetailVO.getApplyDepository());
        purchaseOrderDetailVO.setApplyDepository(drugDepository.getId());
        purchaseOrderDetailVO.setApplyDepositoryName(drugDepository.getName());
        // 查询部门名称
        Dept dept = deptService.getById(drugDepository.getDept());
        purchaseOrderDetailVO.setDept(dept.getId());
        purchaseOrderDetailVO.setDeptName(dept.getName());
        // 根据采购单id查询采购药品列表
        List<PurchaseOrderDrug> drugList = purchaseOrderDrugService.list(new LambdaQueryWrapper<PurchaseOrderDrug>().eq(PurchaseOrderDrug::getPurchaseOrderId, purchaseOrderDetailVO.getId()));
        List<PurchaseOrderOperation> operationList = purchaseOrderOperationService.list(new LambdaQueryWrapper<PurchaseOrderOperation>().eq(PurchaseOrderOperation::getPurchaseOrderId, purchaseOrderDetailVO.getId()));
        // 构建集采列表数据
        Map<String, List<PurchaseOrderOperationVo>> optMap = this.operationToMap(operationList);
        Map<String, PurchaseOrderDetail> drugCodeMap = new HashMap<>();
        for (PurchaseOrderDrug purchaseOrderDrug : drugList) {
            PurchaseOrderDetail purchaseOrderDetail = drugCodeMap.get(purchaseOrderDrug.getDrugCode());
            if (Objects.isNull(purchaseOrderDetail)) {
                purchaseOrderDetail = new PurchaseOrderDetail();
                BeanUtil.copyProperties(purchaseOrderDrug, purchaseOrderDetail);
            }
            List<Long> existDepository = purchaseOrderDetail.getDrugDepositoryVoList().stream().map(DrugDepositoryVo::getId).collect(Collectors.toList());
            if (existDepository.contains(purchaseOrderDrug.getDepositoryId())) continue;
            DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
            BeanUtil.copyProperties(purchaseOrderDrug, drugDepositoryVo);
            drugDepositoryVo.setId(purchaseOrderDrug.getDepositoryId());
            drugDepositoryVo.setName(purchaseOrderDrug.getDepositoryName());
            drugDepositoryVo.setInventory(purchaseOrderDrug.getSourceNum());
            // 每个药品得操作列表
            String key = purchaseOrderDrug.getPurchaseOrderId() + purchaseOrderDrug.getDrugCode();
            List<PurchaseOrderOperationVo> purchaseOrderOperationVos = optMap.get(key);
            if (!CollectionUtils.isEmpty(purchaseOrderOperationVos)) {
                Optional<PurchaseOrderOperationVo> first = purchaseOrderOperationVos.stream().filter(operationVo -> operationVo.getTargetDepositoryId().equals(purchaseOrderDrug.getDepositoryId())).findFirst();
                if (first.isPresent()) {
                    drugDepositoryVo.setPurchaseNum(first.get().getNum());
                }
                purchaseOrderDetail.getDrugDepositoryVoList().add(drugDepositoryVo);
                drugCodeMap.put(purchaseOrderDrug.getDrugCode(), purchaseOrderDetail);
                purchaseOrderDetail.setOperationList(purchaseOrderOperationVos);
            }

        }
        // 药品维度得列表，每个药品添加各个库
        List<PurchaseOrderDetail> purchaseOrderList = new ArrayList<>();
        Map<Long, DrugDepository> allDrugDepository = drugDepositoryService.list().stream().collect(Collectors.toMap(DrugDepository::getId, Function.identity()));
        for (Map.Entry<String, PurchaseOrderDetail> entry : drugCodeMap.entrySet()) {
            PurchaseOrderDetail drugDetail = entry.getValue();
            List<Long> existDepositoryId = drugDetail.getDrugDepositoryVoList().stream().map(DrugDepositoryVo::getId).collect(Collectors.toList());
            for (Long depositoryId : allDrugDepository.keySet()) {
                if (existDepositoryId.contains(depositoryId)) continue;
                DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
                drugDepositoryVo.setId(depositoryId);
                drugDepositoryVo.setName(allDrugDepository.get(depositoryId).getName());
                drugDepositoryVo.setIsTop(allDrugDepository.get(depositoryId).getIsTop());
                drugDepositoryVo.setInventory(0);
                drugDepositoryVo.setDoneInventory(0);
                drugDepositoryVo.setSubInventory(0);
                drugDepositoryVo.setDoneSubInventory(0);
                drugDetail.getDrugDepositoryVoList().add(drugDepositoryVo);
            }
            drugDetail.getDrugDepositoryVoList().sort(Comparator.comparing(DrugDepositoryVo::getId));
            purchaseOrderList.add(drugDetail);
        }
        purchaseOrderDetailVO.setPurchaseOrderDrugList(purchaseOrderList);
        purchaseOrderDetailVO.setDrugTypeNum(drugList.size());

        // 定义采购总数量
        int purchasesDrugNum = 0;
        // 定义总的入库数
        int allGodownNum = 0;
        // 入库单
        for (PurchaseOrderDetail purchaseOrderDrug : purchaseOrderList) {
//            purchasesDrugNum += purchaseOrderDrug.getNum();
            // 定义每个药品已入库数
            int drugGodownNum = 0;
            LambdaQueryWrapper<GodownDrug> godownDrugLambdaQueryWrapper = new LambdaQueryWrapper<>();
            godownDrugLambdaQueryWrapper.eq(GodownDrug::getPurchaseOrderId, id);
            godownDrugLambdaQueryWrapper.eq(GodownDrug::getDrugCode, purchaseOrderDrug.getDrugCode());
            List<GodownDrug> godownDrugList = godownDrugService.list(godownDrugLambdaQueryWrapper);
            List<GodownDrugDetail> godownDrugDetailList = new ArrayList<>();
            for (GodownDrug godownDrug : godownDrugList) {
                GodownDrugDetail godownDrugDetail = new GodownDrugDetail();
                godownDrugDetail.setId(godownDrug.getId());
                godownDrugDetail.setDrugCode(godownDrug.getDrugCode());
                godownDrugDetail.setProductTime(godownDrug.getProductTime());
                godownDrugDetail.setExpirationTime(godownDrug.getExpiration());
                godownDrugDetail.setGodownNum(godownDrug.getPutNum());
                godownDrugDetail.setBatchCode(godownDrug.getBatchCode());
                allGodownNum += godownDrug.getPutNum();
                drugGodownNum += godownDrug.getPutNum();
                godownDrugDetailList.add(godownDrugDetail);
            }
            purchaseOrderDrug.setGodownDrugList(godownDrugDetailList);
//            purchaseOrderDrug.setCanGodownNum(purchaseOrderDrug.getNum() - drugGodownNum);

            // 查询药品表
            Drug drug = drugService.getOne(new LambdaQueryWrapper<Drug>().eq(Drug::getCode, purchaseOrderDrug.getDrugCode()));
            purchaseOrderDrug.setDrugCode(drug.getCode());
            purchaseOrderDrug.setDrugName(drug.getName());
            purchaseOrderDrug.setDrugCommonName(drug.getCommonName());
            purchaseOrderDrug.setDrugSpecs(drug.getSpecs());
            purchaseOrderDrug.setStatus(drug.getStatus());
            purchaseOrderDrug.setForm(drug.getForm());
            purchaseOrderDrug.setFactory(drugFactoryService.getById(drug.getFactory()).getFactory());
            purchaseOrderDrug.setOuterUnit(drug.getOuterUnit());
            purchaseOrderDrug.setMinPurchaseNum(drug.getMinPurchaseNum());
            purchaseOrderDrug.setBuyCycle(drug.getBuyCycle());
            // 库存
            LambdaQueryWrapper<DrugDepositoryDrug> DrugDepositoryDrugWrapper = new LambdaQueryWrapper<>();
            DrugDepositoryDrugWrapper.eq(DrugDepositoryDrug::getDrugCode, purchaseOrderDrug.getDrugCode());
            DrugDepositoryDrugWrapper.eq(DrugDepositoryDrug::getDrugDepositoryId, drugDepository.getId());
            DrugDepositoryDrugWrapper.select(DrugDepositoryDrug::getNums).groupBy(DrugDepositoryDrug::getDrugDepositoryId, DrugDepositoryDrug::getDrugCode);
            DrugDepositoryDrug drugDepositoryDrug = drugDepositoryDrugService.getOne(DrugDepositoryDrugWrapper);
            purchaseOrderDrug.setDepositoryNum(Objects.nonNull(drugDepositoryDrug) ? drugDepositoryDrug.getNums() : 0);
        }
        purchaseOrderDetailVO.setDrugNum(purchasesDrugNum);
        purchaseOrderDetailVO.setGodownStatus(allGodownNum == 0 ? GoDownStatusEnum.PENDING.getCode() :
                purchaseOrderDetailVO.getDrugNum() != allGodownNum ? GoDownStatusEnum.DOING.getCode() : GoDownStatusEnum.DONE.getCode());

        // 审批状态
        AuditFlow auditFlow = auditFlowService.getOne(new LambdaQueryWrapper<AuditFlow>().eq(AuditFlow::getFlowNo, purchaseOrderDetailVO.getCode()));
        if (Objects.nonNull(auditFlow)) {
            purchaseOrderDetailVO.setAuditStatus(auditFlow.getStatus());
            purchaseOrderDetailVO.setStatus(auditFlow.getStatus());
        }
        AuditFlowPreset auditFlowPreset = auditFlowPresetService.getOne(new LambdaQueryWrapper<AuditFlowPreset>().eq(AuditFlowPreset::getBusinessCode, BusinessEnum.PURCHASE_ORDER.getCode()));
        List<AuditFlowDetail> auditFlowDetailList = auditFlowDetailService.list(new LambdaQueryWrapper<AuditFlowDetail>().eq(AuditFlowDetail::getFlowNo, purchaseOrder.getCode()));
        String[] jobDutyList = auditFlowPreset.getJobDuty().split(",");

        AuditFlowPresetVO auditFlowPresetVO = new AuditFlowPresetVO();
        auditFlowPresetVO.setBusinessCode(BusinessEnum.PURCHASE_ORDER.getCode());
        auditFlowPresetVO.setBusinessName(BusinessEnum.PURCHASE_ORDER.getMsg());
        List<JobDutyVO> jobDutyVOList = new ArrayList<>();
        for (int i = 0; i < auditFlowDetailList.size(); i++) {
            JobDutyVO jobDutyVO = new JobDutyVO();
            jobDutyVO.setId(Long.valueOf(jobDutyList[i]));
            JobDuty jobDuty = jobDutyService.getById(Long.valueOf(jobDutyList[i]));
            jobDutyVO.setName(jobDuty.getName());
            AuditFlowDetail auditFlowDetail = auditFlowDetailList.get(i);
            jobDutyVO.setAuditUser(userService.getById(auditFlowDetail.getAuditUserId()));
            List<User> userListByJobDuty = userService.list(new LambdaQueryWrapper<User>().like(User::getJobDuty, jobDuty.getId()));
            userService.list().stream().filter(user -> {
                String[] jobDutyListByUser = user.getJobDuty().split(",");
                for (String s : jobDutyListByUser) {
                    if (Objects.equals(s, jobDuty.getId())) return true;
                }
                return false;
            });
            jobDutyVO.setAuditAvailableUserList(userListByJobDuty);
            jobDutyVOList.add(jobDutyVO);
        }
        auditFlowPresetVO.setJobDutyList(jobDutyVOList);
        purchaseOrderDetailVO.setAuditFlowDetail(auditFlowPresetVO);
        return ApiResult.success(purchaseOrderDetailVO);
    }

    private Map<String, List<PurchaseOrderOperationVo>> operationToMap(List<PurchaseOrderOperation> operationList) {
        Map<String, List<PurchaseOrderOperationVo>> resultMap = new HashMap<>();
        for (PurchaseOrderOperation purchaseOrderOperation : operationList) {
            String key = purchaseOrderOperation.getPurchaseOrderId() + purchaseOrderOperation.getDrugCode();
            List<PurchaseOrderOperationVo> purchaseOrderOperations = resultMap.get(key);
            if (CollectionUtils.isEmpty(purchaseOrderOperations)) purchaseOrderOperations = new ArrayList<>();
            PurchaseOrderOperationVo purchaseOrderOperationVo = new PurchaseOrderOperationVo();
            BeanUtils.copyProperties(purchaseOrderOperation, purchaseOrderOperationVo);
            purchaseOrderOperations.add(purchaseOrderOperationVo);
            resultMap.put(key, purchaseOrderOperations);
        }
        return resultMap;
    }

    @DeleteMapping("/remove/{id}")
    @ApiOperation(value = "删除采购单")
    @Transactional
    public ApiResult<?> delete(@PathVariable int id) {
        purchaseOrderService.removeById(id);
        // 删除药品
        LambdaQueryWrapper<PurchaseOrderDrug> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PurchaseOrderDrug::getPurchaseOrderId, id);
        purchaseOrderDrugService.remove(queryWrapper);
        return ApiResult.success();
    }

    @PostMapping("/addorupdate")
    @ApiOperation(value = "添加/编辑采购单")
    @Transactional
    public ApiResult<?> add(@Valid @RequestBody PurchaseOrderAddReqDTO purchaseOrderAddReqDTO, HttpServletRequest request) {
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        // 获取当前用户登录得库
        List<UserDeptWorkAddressJobOffice> list = (List<UserDeptWorkAddressJobOffice>) CaffeineUtils.get(USER_CACHE);
        UserDeptWorkAddressJobOffice loginUser = list.stream().filter(u -> u.getUserId().equals(userId)).collect(Collectors.toList()).get(0);
        List<DeptListDrugDepVO> depositoryList = (List<DeptListDrugDepVO>) drugDepositoryController.deptList(loginUser.getDeptId()).getData();
        if (CollectionUtils.isEmpty(depositoryList)) return ApiResult.error(DEPOSITORY_NOT_FOUND);
        DeptListDrugDepVO deptListDrugDepVO = depositoryList.get(0);

        // 新增
        if (purchaseOrderAddReqDTO.getId() == null) {

            PurchaseOrder purchaseOrder = new PurchaseOrder();
            BeanUtils.copyProperties(purchaseOrderAddReqDTO, purchaseOrder);
            String code = "CG" + LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
            purchaseOrder.setCode(code);
            purchaseOrder.setApplyDepository(deptListDrugDepVO.getId());
            purchaseOrder.setCreatedBy(userName);
            purchaseOrder.setUpdatedBy(userName);
            purchaseOrderService.save(purchaseOrder);
            if (!CollectionUtils.isEmpty(purchaseOrderAddReqDTO.getPurchaseOrderDrugList())) {
                List<PurchaseOrderDrug> purchaseOrderDrugList = new ArrayList<>();
                List<PurchaseOrderOperation> purchaseOrderOperationList = new ArrayList<>();
                for (PurchaseOrderDetail purchaseOrderDTO : purchaseOrderAddReqDTO.getPurchaseOrderDrugList()) {
                    for (DrugDepositoryVo drugDepositoryVo : purchaseOrderDTO.getDrugDepositoryVoList()) {
                        PurchaseOrderDrug purchaseOrderDrug = new PurchaseOrderDrug();
                        BeanUtil.copyProperties(purchaseOrderDTO, purchaseOrderDrug);
                        purchaseOrderDrug.setPurchaseOrderId(purchaseOrder.getId());
                        purchaseOrderDrug.setDrugCode(purchaseOrderDTO.getDrugCode());
                        purchaseOrderDrug.setDrugStatus(purchaseOrderDTO.getStatus());
                        purchaseOrderDrug.setCreatedBy(userName);
                        purchaseOrderDrug.setUpdatedBy(userName);
                        purchaseOrderDrug.setDepositoryId(drugDepositoryVo.getId());
                        purchaseOrderDrug.setDepositoryName(drugDepositoryVo.getName());
                        purchaseOrderDrug.setSourceNum(drugDepositoryVo.getInventory());
                        purchaseOrderDrug.setDoneInventory(drugDepositoryVo.getDoneInventory());
                        purchaseOrderDrugList.add(purchaseOrderDrug);
                    }
                    // operation
                    if (!CollectionUtils.isEmpty(purchaseOrderDTO.getOperationList())) {
                        for (PurchaseOrderOperationVo purchaseOrderOperation : purchaseOrderDTO.getOperationList()) {
                            purchaseOrderOperation.setPurchaseOrderId(purchaseOrder.getId());
                            purchaseOrderOperation.setCreatedBy(userName);
                            purchaseOrderOperation.setUpdatedBy(userName);
                            PurchaseOrderOperation dbOperation = new PurchaseOrderOperation();
                            BeanUtils.copyProperties(purchaseOrderOperation, dbOperation);
                            purchaseOrderOperationList.add(dbOperation);
                        }
                    }
                }
                purchaseOrderDrugService.saveBatch(purchaseOrderDrugList);
                purchaseOrderOperationService.saveBatch(purchaseOrderOperationList);

            }

            saveAudit(purchaseOrderAddReqDTO.getStatus(), userId, userName, code, purchaseOrderAddReqDTO.getAuditUserIds());

            return ApiResult.success(purchaseOrder);
        }
        // 编辑
        PurchaseOrder checkPurchaseOrder = purchaseOrderService.getById(purchaseOrderAddReqDTO.getId());

        LambdaQueryWrapper<PurchaseOrderDrug> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PurchaseOrderDrug::getPurchaseOrderId, purchaseOrderAddReqDTO.getId());
        purchaseOrderDrugService.remove(queryWrapper);

        LambdaQueryWrapper<PurchaseOrderOperation> queryWrapperOperation = new LambdaQueryWrapper<>();
        queryWrapperOperation.eq(PurchaseOrderOperation::getPurchaseOrderId, purchaseOrderAddReqDTO.getId());
        purchaseOrderOperationService.remove(queryWrapperOperation);

        PurchaseOrder purchaseOrder = new PurchaseOrder();
        BeanUtils.copyProperties(purchaseOrderAddReqDTO, purchaseOrder);
        purchaseOrder.setUpdatedBy(userName);
        purchaseOrderService.updateById(purchaseOrder);

        List<PurchaseOrderDrug> purchaseOrderDrugList = new ArrayList<>();
        List<PurchaseOrderOperation> purchaseOrderOperationList = new ArrayList<>();
        for (PurchaseOrderDetail purchaseOrderDTO : purchaseOrderAddReqDTO.getPurchaseOrderDrugList()) {
            for (DrugDepositoryVo drugDepositoryVo : purchaseOrderDTO.getDrugDepositoryVoList()) {
                PurchaseOrderDrug purchaseOrderDrug = new PurchaseOrderDrug();
                BeanUtils.copyProperties(purchaseOrderDTO, purchaseOrderDrug);
                purchaseOrderDrug.setPurchaseOrderId(purchaseOrder.getId());
                purchaseOrderDrug.setDrugCode(purchaseOrderDTO.getDrugCode());
                purchaseOrderDrug.setDrugStatus(purchaseOrderDTO.getStatus());
                purchaseOrderDrug.setCreatedBy(userName);
                purchaseOrderDrug.setUpdatedBy(userName);
                purchaseOrderDrug.setDepositoryId(drugDepositoryVo.getId());
                purchaseOrderDrug.setDepositoryName(drugDepositoryVo.getName());
                purchaseOrderDrug.setSourceNum(drugDepositoryVo.getInventory());
                purchaseOrderDrug.setDoneInventory(drugDepositoryVo.getDoneInventory());
                purchaseOrderDrugList.add(purchaseOrderDrug);
            }
            if (!CollectionUtils.isEmpty(purchaseOrderDTO.getOperationList())) {
                for (PurchaseOrderOperationVo purchaseOrderOperation : purchaseOrderDTO.getOperationList()) {
                    purchaseOrderOperation.setDrugCode(purchaseOrderDTO.getDrugCode());
                    purchaseOrderOperation.setPurchaseOrderId(purchaseOrder.getId());
                    purchaseOrderOperation.setNum(purchaseOrderOperation.getNum());
                    purchaseOrderOperation.setCreatedBy(userName);
                    purchaseOrderOperation.setUpdatedBy(userName);
                    PurchaseOrderOperation dbOperation = new PurchaseOrderOperation();
                    BeanUtils.copyProperties(purchaseOrderOperation, dbOperation);
                    purchaseOrderOperationList.add(dbOperation);
                }
            }
        }
        purchaseOrderDrugService.saveBatch(purchaseOrderDrugList);
        purchaseOrderOperationService.saveBatch(purchaseOrderOperationList);
        saveAudit(purchaseOrderAddReqDTO.getStatus(), userId, userName, checkPurchaseOrder.getCode(), purchaseOrderAddReqDTO.getAuditUserIds());
        return ApiResult.success(purchaseOrder);
    }

    private void saveAudit(Integer status, Long userId, String userName, String code, List<Long> auditUserIds) {
        // 提交之后添加审批流
        if (PurchaseStatusEnum.COMMIT.getCode().equals(status))  {
            // 修改后刷新审批流
            auditFlowService.remove(new LambdaQueryWrapper<AuditFlow>().eq(AuditFlow::getFlowNo, code));
            auditFlowDetailService.remove(new LambdaQueryWrapper<AuditFlowDetail>().eq(AuditFlowDetail::getFlowNo, code));
            // 添加审批流
            AddAuditFlowReqDTO addAuditFlowReqDTO = new AddAuditFlowReqDTO();
            addAuditFlowReqDTO.setTitle(FlowNoPrefixEnum.PURCHASE.getMsg());
            addAuditFlowReqDTO.setBusinessCode(BusinessEnum.PURCHASE_ORDER.getCode());
            addAuditFlowReqDTO.setAuditUserIds(auditUserIds);
            addAuditFlowReqDTO.setUserId(userId);
            addAuditFlowReqDTO.setUserName(userName);
            addAuditFlowReqDTO.setFlowNo(code);
            addAuditFlowReqDTO.setMessageType(MessageTypeEnum.PURCHASE.getCode());
            auditFlowPresetExtendService.addAuditFlow(addAuditFlowReqDTO);
        }
    }

    @PostMapping("/godown-drug")
    @ApiOperation(value = "入库")
    @Transactional
    public ApiResult<?> goDownDrug2(@Valid @RequestBody GoDownDrugReqDTO goDownDrugReqDTO, HttpServletRequest request) {
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        List<GodownDrug> godownDrugList = new ArrayList<>();
        for (GoDownDrugReqDTO.GoDownDrugBO goDownDrugBO : goDownDrugReqDTO.getPurchaseOrderDrugList()) {
            GodownDrug godownDrug = new GodownDrug();
            godownDrug.setDrugCode(goDownDrugBO.getDrugCode());
            godownDrug.setPurchaseOrderId(goDownDrugReqDTO.getPurchaseOrderId());
            godownDrug.setOperationId(goDownDrugBO.getOperationId());
            godownDrug.setSupplier(goDownDrugBO.getSupplier());
            godownDrug.setSource(goDownDrugReqDTO.getSource());
            godownDrug.setBatchCode(goDownDrugBO.getBatchCode());
            godownDrug.setProductTime(goDownDrugBO.getProductTime());
            godownDrug.setQualityTime(goDownDrugBO.getQualityTime());
            godownDrug.setExpiration(goDownDrugBO.getExpiration());
            godownDrug.setPutNum(goDownDrugBO.getPutNum());
            godownDrug.setCreatedBy(userName);
            godownDrug.setUpdatedBy(userName);
            godownDrugList.add(godownDrug);
        }
        godownDrugService.saveBatch(godownDrugList);

        // 入库房
        List<DrugDepositoryDrug> addDrugDepositoryDrugList = new ArrayList<>();
        List<DrugDepositoryDrug> updateDrugDepositoryDrugList = new ArrayList<>();
        for (GoDownDrugReqDTO.GoDownDrugBO goDownDrugBO : goDownDrugReqDTO.getPurchaseOrderDrugList()) {
            DrugDepositoryDrug drugDepositoryDrug = drugDepositoryDrugService.getOne(new LambdaQueryWrapper<DrugDepositoryDrug>()
                    .eq(DrugDepositoryDrug::getDrugCode, goDownDrugBO.getDrugCode())
                    .eq(DrugDepositoryDrug::getDrugDepositoryId, goDownDrugReqDTO.getDrugDepositoryId())
                    .eq(DrugDepositoryDrug::getProductTime, goDownDrugBO.getProductTime())
                    .eq(DrugDepositoryDrug::getExpiration, goDownDrugBO.getExpiration())
            );
            if (drugDepositoryDrug == null) {
                drugDepositoryDrug = new DrugDepositoryDrug();
                drugDepositoryDrug.setDrugDepositoryId(goDownDrugReqDTO.getDrugDepositoryId());
                drugDepositoryDrug.setDrugCode(goDownDrugBO.getDrugCode());
                drugDepositoryDrug.setNum(goDownDrugBO.getPutNum());
                drugDepositoryDrug.setProductTime(goDownDrugBO.getProductTime());
                drugDepositoryDrug.setQualityTime(goDownDrugBO.getQualityTime());
                drugDepositoryDrug.setExpiration(goDownDrugBO.getExpiration());
                drugDepositoryDrug.setCreatedBy(userName);
                drugDepositoryDrug.setUpdatedBy(userName);
                addDrugDepositoryDrugList.add(drugDepositoryDrug);
            } else {
                // 可能导致数量有误，操作不频繁先不关心 应该是column = column + num
                drugDepositoryDrug.setNum(drugDepositoryDrug.getNum() + goDownDrugBO.getPutNum());
                drugDepositoryDrug.setUpdatedBy(userName);
                updateDrugDepositoryDrugList.add(drugDepositoryDrug);
            }
        }
        drugDepositoryDrugService.saveBatch(addDrugDepositoryDrugList);
        drugDepositoryDrugService.updateBatchById(updateDrugDepositoryDrugList);

        return ApiResult.success();
    }

}
